home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 2: CDPD 1
/
Almathera Ten on Ten - Disc 2: CDPD 1.iso
/
pd
/
201-225
/
224
/
climax
/
climax.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-03-13
|
12KB
|
450 lines
#ifdef This_Is_A_Big_Comment
Have you ever wanted CLI on a custom screen with 25 lines of 80 characters?
Here it is! By Paul Kienitz, 11/27/88. When compiling with Aztec C, DO NOT
use the +M option (stack checking). There are some provisions for compiling
it without Aztec, but they are UNTESTED AND PROBABLY INCOMPLETE. Last
revision date: 3/26/89.
The major question is, how do we get EndCLI to wait for filehandles on the
window to close? Is it a ConMan problem? YES. If I use an ordinary window,
the CON handler waits; only with a strange Wnnnnnn window does the handler
close the window when I Close the file handle without seeing if anyone else
is still using it. And how do I tell whether Shell-Seg is resident? Scan
the resident list for something the right size? No, don't bother. How do
you make a failing Workbench program beep the screen and set "last error"?
With the startup message reply somehow? I don't think so.
Improvements needed:
=> o Make it work without ConMan.
=> o Make it wait for other things with window filehandles to quit. I guess
this comes down to getting rid of ConMan dependency.
o Make it not need to be "Run CLImax". Create global permanent piece of
cleanup code and patch it into file handle's closefunc field?
o hot key to bring to front and activate? Make your own, I don't need one.
o Invisible full size screen depth gadgets? Nah.
o Command line options for colors, wbenchscreen?, overscanmargin?, startup
command?. ToolTypes for all those plus CD.
o After I've got FastExNext down, how about FastExecute?
o There's not much I can do to reduce the memory consumption. Aside from
the 33K of chip ram for the screen, it uses no more than a Workbench
Shell does, which is a lot (22K). It's only about 10K for a NewCLI.
That's with ConMan; it's probably less with vanilla CON:. The
experimental cli-cleans-itself-up version would probably use less
memory that the waiting-process version.
#endif /* big comment */
#define INTUITIONPRIVATE
/* So IntuitionBase->Preferences is visible. We're examining only. */
#include <exec/exec.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <libraries/dosextens.h>
#ifdef AZTEC_C
#include <functions.h> /* modified so BPTR () functions are declared so */
#endif
#include <Paul.h>
/* screen/window stuff based on copied leo schwab code */
#define XSIZE 640
#define GREENISHNESS {0x484, 0x000, 0x0b0, 0xcc0}
#define OverscanMargin 4
/* we overscan so there's a small space at the top to pull the screen down
with; lets you see part of the screen depth gadgets */
#define SCLI struct CommandLineInterface
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *scr;
struct Window *win;
extern struct WBStartup *WBenchMsg;
adr IconBase;
adr wopter;
struct Process *me;
bool lace = false, unshelled = false,
greenify = false, baloney = false;
UBYTE scr_tit[] = " CLImax screen "; /* won't actually show */
struct NewScreen scrdef = {
0, 0, XSIZE, 47L, /* YSIZE will be set later */
2, /* 4 colors */
0, 0, /* detail pen = background so no white stripe at top */
HIRES, CUSTOMSCREEN,
null, scr_tit, null, null /* no special font, gadget, or bitmap */
};
struct NewWindow windef = {
0, OverscanMargin, XSIZE, 44L, /* YSISE will be set later */
0, 1,
0L,
ACTIVATE | BACKDROP | BORDERLESS,
null, null, null, /* no special gadget or checkmark, no title */
69L, /* screen pointer; will get set later */
null, /* no custom bitmap */
0, 0, 0, 0, /* ignored */
CUSTOMSCREEN
};
/*
#define puf(S, N) (sprintf(buf, S, N), spew(buf))
#define puff(S, N, NN) (sprintf(buf, S, N, NN), spew(buf))
char buf[256];
*/
void spew(s) str s;
{
register BPTR o = Output();
register long l = strlen(s);
if (o) Write(o, s, l);
}
openstuff ()
{ ushort *wbcolor, tallth;
static ushort lacecolor[4] = GREENISHNESS;
long collor; /* that's how Joan spelled it once */
struct ViewPort *vp;
IntuitionBase = (adr) OpenLibrary ("intuition.library", 1L);
GfxBase = (adr) OpenLibrary ("graphics.library", 1L);
/* Look Ma, no error check! */
tallth = IntuitionBase->MaxDisplayHeight & ~15;
if (lace) scrdef.ViewModes = HIRES | LACE;
else tallth >>= 1;
windef.Height = tallth;
scrdef.Height = tallth + OverscanMargin;
if (!(scr = OpenScreen (&scrdef))) {
spew ("Can't open screen.\n");
closestuff();
exit (10);
}
windef.Screen = scr;
if (!(win = OpenWindow (&windef))) {
spew ("Can't open window.\n");
closestuff();
exit (10);
}
ShowTitle(scr, FALSE);
vp = &(scr -> ViewPort); /* set colors according to Preferences */
if (greenify) wbcolor = lacecolor; /* except when G option */
else wbcolor = &IntuitionBase->Preferences->color0;
/* nothing multitasking-unsafe about examining in place, right? */
for (collor = 0; collor <= 3; collor++, wbcolor++)
SetRGB4(vp, collor, (*wbcolor >> 8) & 15L,
(*wbcolor >> 4) & 15L,
*wbcolor & 15L);
}
closestuff ()
{
register struct Window *w;
me->pr_WindowPtr = wopter;
/* ConMan 1.3 closes the window when you close the file handle. Older ConMen
don't. We have to handle both cases, so we see if the window is still
attached to the screen: */
if (scr && win)
for (w = scr->FirstWindow; w; w = w->NextWindow)
if (w == win) {
CloseWindow(win);
break;
}
if (scr) CloseScreen (scr);
if (GfxBase) CloseLibrary (GfxBase);
if (IntuitionBase) CloseLibrary (IntuitionBase);
}
/* strlen that doesn't look past length 255 */
int blen(m) register str m;
{ register int l;
for(l = 0; l < 255; l++,m++) if (!*m) break;
return (l);
}
BPTR bstr(s) str s;
{
int l = blen(s);
long al = (l + 8) & ~3;
str b;
if (!(b = AllocPZ(al)))
return (null);
*(long *) b = al;
b[4] = l;
strncpy(b + 5, s, l);
return (((long) b + 4) >> 2);
}
void freebeast(b) BPTR b;
{
long *p = bip(long, b);
FreeMem(p - 1, p[-1]);
}
BPTR CopyWBPath()
{
struct Process *wb = (adr) FindTask("Workbench");
SCLI *wbclap;
BPTR *wext, *mext, *lastmext, newpath = null;
lastmext = &newpath;
if (!wb) return (null);
if (!(wbclap = gbip(wb->pr_CLI))) return (null);
for (wext = gbip(wbclap->cli_CommandDir); wext; wext = gbip(*wext)) {
if (!(mext = AllocP(2 * sizeof(BPTR))))
break;
*lastmext = (long) mext >> 2;
lastmext = mext;
mext[1] = DupLock(wext[1]);
mext[0] = null;
}
return (newpath);
}
void FakeCLI()
{
SCLI *clap;
if (!(clap = NewPZ(SCLI))) /* clear|public */
return;
baloney = true;
me->pr_CLI = (long) clap >> 2;
clap->cli_SetName = bstr("SYS:");
clap->cli_Prompt = bstr("%N> ");
clap->cli_DefaultStack = 1000L;
CurrentDir(RLock("SYS:")); /* old CD was zero */
clap->cli_CommandDir = CopyWBPath();
}
void NukePath(path) BPTR path;
{
BPTR *next, *p;
for (p = gbip(path); p; p = next) {
next = gbip(p[0]);
if (p[1]) UnLock(p[1]);
FreeMem(p, 2L * sizeof(BPTR));
}
}
void StopFakery()
{
BPTR cd = CurrentDir(null);
SCLI *clap = gbip(me->pr_CLI);
if (cd) UnLock(cd);
if (!clap) return;
freebeast(clap->cli_SetName);
freebeast(clap->cli_Prompt);
NukePath(clap->cli_CommandDir);
me->pr_CLI = null;
Free(SCLI, clap);
}
void wandle()
{
struct DiskObject *bob;
str toop;
register char c;
if (!(IconBase = OpenLibrary("icon.library", 0L))) return;
CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
if (bob = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)) {
if (toop = FindToolType(bob->do_ToolTypes, "OPTION"))
for (c = tolower(*toop); c; c = tolower(*++toop)) {
if (c == 'v') unshelled = true;
else if (c == 'g') greenify = true;
else if (c == 'i') lace = true;
}
FreeDiskObject(bob);
}
CurrentDir(null);
CloseLibrary(IconBase);
IconBase = null;
}
int word, chair, ac; str *av;
char nerg()
{
#ifdef AZTEC_C
if (((str) av)[chair]) return (((str) av)[chair++]);
else return (0);
#else
if (av[word][chair]) return (av[word][chair++]);
else if (av[++word]) return (av[word][chair = 0]);
else return (0);
#endif
}
void handle(argc, argv) int argc; str argv[];
{
char c;
bool kelp = false;
ac = argc; av = argv; word = 1; chair = 0;
lace = false;
for (c = tolower(nerg()); c; c = tolower(nerg())) {
if (c == 'v') unshelled = true;
if (c == 'i') lace = true;
if (c == 'g') greenify = true;
if (c == '?' | c == 'h') kelp = true;
}
if (kelp) {
spew(
"\nCLImax by Paul Kienitz -- usage:\n\n"
" Run > nil: CLImax [V] [I] [G]\n\n"
"Spaces and letter cases and order of appearence never matter.\n"); spew(
"V (vanilla) means start with s:CLI-Startup instead of s:Shell-Startup.\n"
"I means make an interlace screen.\n"); spew(
"G means use black-on-greenish (good for interlace) instead of\n"
" the Workbench colors (maybe someday there'll be an RGB option).\n"
"? or H means show this message.\n\n"); spew(
"For Workbench, use a tooltype OPTION= followed by V, I, and/or G.\n\n");
closestuff();
exit(0);
}
}
main(argc, argv) int argc; stray argv;
{
char boof[50];
str command;
BPTR window_handle, L, Seg = 1;
#ifndef AZTEC_C
me = (adr) FindTask(null);
=== do something to set WBenchMsg ===
#endif
if (WBenchMsg) wandle();
else handle(argc, argv);
/* spew("Maximum CLI for you, from Paul Kienitz. Public Domain.\n"); */
openstuff();
wopter = me->pr_WindowPtr;
me->pr_WindowPtr = -1L;
#ifdef EXPERIMENTAL
window_handle = OOpen("nil:");
if (!unshelled && (L = RLock("C:NewShell"))) {
strcpy(boof, "c:newshell >nil: ");
UnLock(L);
} else if (L = RLock("C:NewCLI")) {
strcpy(boof, "c:newcli >nil: ");
UnLock(L);
}
speck(boof, win);
me->pr_WindowPtr = (adr) win; /* setting gets passed to child cli */
/* if (Seg = LoadSeg("L:CLImax-Cleanup")) */
if (!Execute(boof, null, window_handle))
spew("Can't start CLI. ConMan not present?\n");
else { win = null; scr = null; } /* prevent closure */
/* else spew("Can't find L:CliMAX-Cleanup.\n"); */
#else
if (!unshelled && (L = RLock("S:Shell-Startup"))) {
command = "Execute S:Shell-Startup";
UnLock(L);
} else if (L = RLock("S:CLI-Startup")) {
command = "Execute S:CLI-Startup";
UnLock(L);
} else command = "";
if (!me->pr_CLI) FakeCLI();
boof[0] = 0;
speck(boof, win);
window_handle = NOpen(boof);
me->pr_WindowPtr = (adr) win; /* setting gets passed to child cli */
if (window_handle) {
Execute(command, window_handle, null);
/* wait for other things using window_handle to stop! */
Close(window_handle);
} else spew("Can't open the CON: for the window. ConMan absent?\n");
if (baloney) StopFakery();
#endif
closestuff();
}
speck(b, a) str b; long a;
{
short hid, nyb, blem;
strcat(b, "CON:Wxxxxxx"); /* uses ConMan */
blem = strlen(b) - 1;
for (hid = 0; hid <= 5; hid++) {
nyb = (a >> (4*hid)) & 15;
b[blem - hid] = (nyb >= 10 ? (char) nyb + 'A' - 10 : (char) nyb + '0');
}
}
/* reduce size by a few K: */
#ifdef AZTEC_C
char arg[256];
void _cli_parse(alen, aptr) long alen; str aptr;
{ strncpy(arg, aptr, (int) alen); arg[alen - 1] = 0; }
_main(alen, aptr) long alen; str aptr; /* simplified startup code */
{
me = (struct Process *) FindTask(null);
if (me->pr_CLI) {
_cli_parse(alen, aptr);
WBenchMsg = null;
} else {
WaitPort(&me->pr_MsgPort);
WBenchMsg = (adr) GetMsg(&me->pr_MsgPort);
}
main(1, arg);
exit(0);
}
exit(code) int code;
{
if (WBenchMsg) {
Forbid();
ReplyMsg(WBenchMsg);
}
Exit((long) code);
}
#endif